// @Author EthanScriptOn
// @Desc
package log_filter

type JudgeTag string

type JudgeFunc func(interface{}) (bool, error)
type CompositeJudgeFunc func() JudgeFunc

var CompositeChecker = func(checkers ...JudgeFunc) JudgeFunc {
	return func(log interface{}) (bool, error) {
		for _, checker := range checkers {
			isChecker, err := checker(log)
			if err != nil || !isChecker {
				return false, err
			}
		}
		return true, nil
	}
}

var DefaultFilterChecker = &FilterChecker{
	checkers:   make(map[JudgeTag]JudgeFunc),
	composites: make(map[JudgeTag]CompositeJudgeFunc),
}

type FilterChecker struct {
	checkers   map[JudgeTag]JudgeFunc
	composites map[JudgeTag]CompositeJudgeFunc
}

func (f *FilterChecker) AddChecker(name JudgeTag, judge JudgeFunc) {
	f.checkers[name] = judge
}

func (f *FilterChecker) AddComposite(name JudgeTag, composite CompositeJudgeFunc) {
	f.composites[name] = composite
}

func (f *FilterChecker) GetChecker(name JudgeTag) (JudgeFunc, bool) {
	if checker, ok := f.checkers[name]; ok {
		return checker, true
	}
	if composite, ok := f.composites[name]; ok {
		judgeFuncCache := composite()
		f.AddChecker(name, judgeFuncCache)
		return judgeFuncCache, true
	}
	return nil, false
}
